package cn.zyyl.ai.face;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.os.Environment;
import android.util.Log;

import com.mw.sotest.MyApp;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;


public class FaceDetector2 {

    private static final String TAG = FaceDetector2.class.getSimpleName();
    private Context mContext;



    /**
     * \brief construct an facedetector
     * \param model model path
     */
    public FaceDetector2() {
        mContext = MyApp.getInstance();
    }

    private static class InstanceHolder{
        private final static FaceDetector2 INSTANCE = new FaceDetector2();
    }
    public static FaceDetector2 getInstance(){
        return InstanceHolder.INSTANCE;
    }


    /**
     * 初始化引擎，加载模式文件
     */
    public void loadEngine(String fdModelFile,String pdModelFile,String frModelFile,String facesPath) {
        if (null == fdModelFile || "".equals(fdModelFile) ||
            null == pdModelFile || "".equals(pdModelFile) ||
            null == frModelFile || "".equals(frModelFile)
        ) {
            Log.w(TAG, "detectModelFile file path is invalid!");
            return;
        }

        Log.w(TAG, "fdModelFile file path is :" + fdModelFile);
        Log.w(TAG, "pdModelFile file path is :" + pdModelFile);
        Log.w(TAG, "frModelFile file path is :" + frModelFile);
        this.construct(fdModelFile,pdModelFile,frModelFile,80,1,facesPath,true);
        //this.constructv1(fdModelFile);
    }

    public void loadEngine(String facesPath) {
        if (null == mContext) {
            Log.w(TAG, "please call initial first!");
            return;
        }
        loadEngine(getPath("fd_2_00.dat", mContext),getPath("pd_2_00_pts5.dat", mContext),getPath("fr_2_10.dat", mContext),facesPath);
    }


    protected void finalize() throws Throwable {
        super.finalize();
        this.dispose();
    }





    public byte[] getPixelsBGR(Bitmap image) {
        // calculate how many bytes our image consists of
        int bytes = image.getByteCount();

        ByteBuffer buffer = ByteBuffer.allocate(bytes); // Create a new buffer
        image.copyPixelsToBuffer(buffer); // Move the byte data to the buffer

        byte[] temp = buffer.array(); // Get the underlying array containing the data.

        byte[] pixels = new byte[(temp.length/4) * 3]; // Allocate for BGR

        // Copy pixels into place
        for (int i = 0; i < temp.length/4; i++) {

            pixels[i * 3] = temp[i * 4 + 2];		//B
            pixels[i * 3 + 1] = temp[i * 4 + 1]; 	//G
            pixels[i * 3 + 2] = temp[i * 4 ];		//R

        }

        return pixels;
    }

    /***//**
     * 图片去色,返回灰度图片
     * @param bmpOriginal 传入的图片
     * @return 去色后的图片
     */
    public static Bitmap toGrayscale(Bitmap bmpOriginal) {
        int width, height;
        height = bmpOriginal.getHeight();
        width = bmpOriginal.getWidth();

        Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        Canvas c = new Canvas(bmpGrayscale);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
        paint.setColorFilter(f);
        c.drawBitmap(bmpOriginal, 0, 0, paint);
        return bmpGrayscale;
    }


    //该函数主要用来完成载入外部模型文件时，获取文件的路径加文件名
    public static String getPath(String file, Context context) {
        AssetManager assetManager = context.getAssets();
        BufferedInputStream inputStream = null;
        try {
            inputStream = new BufferedInputStream(assetManager.open(file));
            byte[] data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();
            File outFile = new File(context.getFilesDir(), file);
            FileOutputStream os = new FileOutputStream(outFile);
            os.write(data);
            os.close();
            return outFile.getAbsolutePath();
        } catch (IOException ex) {
            Log.i("FileUtil", "Failed to upload a file");
        }
        return "";
    }


    static {
        System.loadLibrary("SeetaFaceJNI");
    }

    public native int construct(String fdModel,String pdModel,String frModel,int minFaceSize,int isItProvidePoints,String faceFilesPath,boolean logSwitch);
    //public native int constructv1(String fdModel);
    public native int dispose();
    public native int Detect(int width,int height,int channels,int length,byte[] imgBytes,SeetaRect rect1,SeetaRect rect2,SeetaPointsFace seetaPointsFace);
    public native int Register(int width,int height,int channels,int length,byte[] imgBytes,String faceFilesPath);
    public native String version();
    public native int facesCount();
    public native long[] DBIds();
    public native boolean deleteFace(long id,String faceFilesPath);
    //-2:FD is null ｜ -3:no face ｜ 大于等于零为返回的索引ID号
    public native int Recognizer(int width,int height,int channels,int length,byte[] imgBytes);

    public native float QA(int width,int height,int channels,int length,byte[] imgBytes);

}
